.data
	.p2align 4
	.globl IDT
IDT:
	.rept 256
	.word 0, 0, 0, 0
	.endr
idtptr:
	.word (256 * 8 - 1)
	.long IDT

STACK_SIZE = 0x1000

	.globl 	_start
	.globl 	osStart
	.globl shut_down

.text
.code32
_start:
	jmp establish_stack

dead:	jmp dead

establish_stack:
	movl	$_end, %eax
	addl	$STACK_SIZE, %eax
	andl	$0xffffffc0, %eax
	movl	$0x80000, %eax	
	
	movl	%eax, %esp
	movl	%eax, %ebp

# Zero out the BSS segment
zero_bss:
	cld
	movl	$_end, %ecx
	movl	$_bss_start, %edi
	subl	%edi, %ecx
	shrl	%ecx
	shrl	%ecx
	
	xorl	%eax, %eax
	repne
	stosl

# Interrupt
setup_idtptr:
	call setup_idt
	lidt idtptr

# Transfer control to main
to_main:
	call osStart
	jmp shut_down
setup_idt:
    movl $ignore_int1, %edx
    movl $0x0008ffff, %eax
    movw %dx, %ax
    movw $0x8E00, %dx
    movl $IDT, %edi
    mov $256, %ecx

rp_sidt:
    movl %eax, (%edi)
    movl %edx, 4(%edi)
    addl $8, %edi
    dec %ecx
    jne rp_sidt
	
	mov $(32 * 8), %ecx

    movl $time_interrupt, %edx
	call init_syscall

    movl $keyboard_interrupt, %edx
    call init_syscall

	mov $(128 * 8), %ecx
    movl $system_call, %edx
	call init_syscall

	sti
	ret

	# .p2align 4
keyboard_interrupt:
	cld
	pushf
	pusha
	call keyboardInterrupt
	popa
	popf
	iret

	# .p2align 4
time_interrupt:
	cld
	pushf
	pusha
	call tick
	popa
	popf
	iret

system_call:
	cld
	pushf
	# pusha
	push %esp
	# push %eax
	push %edx
	push %ecx
	push %ebx
	push %ebp
	push %esi
	push %edi
	call syscall
	pop %edi
	pop %esi
	pop %ebp
	pop %ebx
	pop %ecx
	pop %edx
	# pop %eax
	pop %esp
	# popa
	popf
	iret

	# .p2align 4
ignore_int1:
	cld
	pusha
	call ignoreIntBody
	popa
	iret

init_syscall:
    movl $0x00080000, %eax
    movw %dx, %ax
    movw $0x8E00, %dx
    movl $IDT, %edi
    addl %ecx, %edi
    movl %eax, (%edi)
    movl %edx, 4(%edi)
	addl $8, %ecx
	ret

shut_down: